home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / dsort / dstoptn.asm < prev    next >
Encoding:
Assembly Source File  |  1993-07-08  |  26.9 KB  |  1,032 lines

  1.     page    96,132
  2. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  3. ;§                                                                          §
  4. ;§              ディレクトリエントリ  ソート  ユーティリティ                §
  5. ;§                                                                          §
  6. ;§                                     DSORT.EXE  Ver1.30    §
  7. ;§                                                                          §
  8. ;§              Copyright (C) by 福地 邦雄 1991-1992. All rights reserved.  §
  9. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  10.     .MODEL  SMALL,C
  11. ;
  12.     public  options,usageout,dirlist,dirfind,strcopywild
  13.     extrn   sweep:word,sortexec:word,recursive:word,dirgather:word
  14.     extrn   dta:dword,srchname:dword,namebuff:dword,namebuffsiz:word
  15.     extrn   dirtype:word,fattype:word,attribute:word,clustcount:word
  16.     extrn   driveno:word,clustsize:word
  17.     extrn   fatbuff:word,dirbuff:word,sortbuff:word,sortcount:word
  18.     extrn   drvinf:byte,clustsect:word,subsearch:word
  19.     extrn   sortfuncs:word,subchain:word,wildcard:byte,pathbuff:byte
  20.     extrn   usagemsg:byte,_msgsize:abs
  21.     extrn   abort:near
  22.     extrn   errorno:word
  23. ;
  24.     PUBLIC  setsortfunc,setsortobj,cmpdummy,cmpdirf,cmpfull,cmpname
  25.     PUBLIC  cmpextn,cmpsize,cmpdate,cmptime,strncmp,chrtypes,pathsep
  26. ;
  27. REVERSE equ 1
  28. NORMAL  equ 0
  29. TAIL    equ 1
  30. HEAD    equ 0
  31. YES     equ 1
  32. NO      equ 0
  33. TAB     equ 9
  34. CR      equ 0dh
  35. LF      equ 0ah
  36. DEFAULT equ 031h
  37. ARCHIVE equ 020h
  38. SUBDIR  equ 010h
  39. VOLUME  equ 008h
  40. HIDDEN  equ 004h
  41. SYSTEM  equ 002h
  42. RDONLY  equ 001h
  43. ;
  44.     .code
  45. ;
  46. ;------------------------------------------------------------------------------
  47. ;
  48. ;   options
  49. ;       オプション指定の評価とディレクトリのリストを取る
  50. ;
  51. ;   TYPE    near call
  52. ;   IN  AX アーギュメント数
  53. ;       SS:BP アーギュメントポインタリストの先頭アドレス
  54. ;   OUT 特になし
  55. ;   保存レジスタ    ds
  56. ;
  57. ;------------------------------------------------------------------------------
  58. ;
  59. options proc
  60. ;
  61.     cld
  62.     push    ax
  63.     mov     ah,2fh                  ; Disk Transfer Address 取得
  64.     int     21h
  65.     lea     bx,[bx+1eh]             ; DTAのファイル名オフセット
  66.     mov     word ptr dta,bx
  67.     mov     word ptr dta+2,es
  68.     pop     bx
  69.     mov     sortfuncs,offset _text:cmpdummy ; ダミーのソート比較関数セット
  70.     mov     word ptr sortfuncs+2,NORMAL
  71.     mov     si,offset sortfuncs+4
  72.     mov     attribute,DEFAULT       ; ソート対象属性のデフォルトセット
  73. ;   @do until
  74. @d0001:
  75.         les     di,[bp]
  76. ;       @cbegin
  77. ;       @case (byte ptr es:[di],=,'-'),S
  78.           cmp   byte ptr es:[di],'-'
  79.           jne   @c0002
  80.             call    setsortfunc
  81. ;       @case (byte ptr es:[di],=,'+'),S
  82.           jmp short @c0001
  83. @c0002:
  84.           cmp   byte ptr es:[di],'+'
  85.           jne   @c0003
  86.             call    setsortobj
  87. ;       @other
  88.           jmp short @c0001
  89. @c0003:
  90.             mov     word ptr srchname,di    ; ディレクトリ名リストの作成
  91.             mov     word ptr srchname+2,es
  92.             call    dirlist
  93. ;       @cend
  94. @c0001:
  95.         add     bp,4                ; 次のアーギュメントへ
  96.         dec     bx
  97. ;   @doend (zf,on)
  98.       jnz   @d0001
  99. ;   @if (si,=,offset sortfuncs+4)
  100.       cmp   si,offset sortfuncs+4
  101.       jne   @i0001
  102.         mov     word ptr [si],offset cmpfull    ; デフォルトの比較関数セット
  103.         mov     word ptr [si+2],NORMAL
  104.         lea     si,[si+4]
  105. ;   @ifend
  106. @i0001:
  107.     not     attribute               ; ソート対象属性を反転させたものを使う
  108.     mov     word ptr [si],0         ; ソート比較関数リストのエンドマーク
  109.     les     di,namebuff             ; ディレクトリ名リストのエンドマーク
  110.     mov     word ptr es:[di],0
  111. ;   @if (word ptr es:[0],=,0)
  112.       cmp   word ptr es:[0],0
  113.       jne   @i0002
  114.         jmp     usageout            ; ディレクトリ無しの時、ヘルプ表示
  115. ;   @ifend
  116. @i0002:
  117.     ret
  118. ;
  119. options endp
  120. ;
  121. ;------------------------------------------------------------------------------
  122. ;
  123. ;   usageout
  124. ;       ヘルプメッセージを表示して終了
  125. ;
  126. ;   TYPE    near call
  127. ;   IN  なし
  128. ;   OUT なし
  129. ;   保存レジスタ    なし
  130. ;
  131. ;------------------------------------------------------------------------------
  132. ;
  133. usageout    proc
  134. ;
  135.     mov     errorno,1
  136.     mov     dx,offset usagemsg
  137.     mov     cx,_msgsize
  138.     jmp     abort
  139. ;
  140. usageout    endp
  141. ;
  142. ;------------------------------------------------------------------------------
  143. ;
  144. ;   setsortfunc
  145. ;       ソート機能指定オプションの評価と、比較関数リストの作成
  146. ;
  147. ;   TYPE    near call
  148. ;   IN      AL アーギュメント文字
  149. ;           DS:SI 比較関数リストアドレス
  150. ;   OUT     SI += 4 
  151. ;   保存レジスタ    bx,cx,dx,di,bp,ds,es
  152. ;
  153. ;------------------------------------------------------------------------------
  154. ;
  155. setsortfunc proc
  156. ;
  157.     inc     di
  158. ;   @do repeat
  159. @d0002:
  160.         mov     al,es:[di]
  161.         inc     di
  162. ;       @if (al,=,0)
  163.           or    al,al
  164.           jne   @i0003
  165. ;           @doexit
  166.               jmp   @d0003
  167. ;       @ifend
  168. @i0003:
  169. ;       @if (al,>=,'a'),S           ; 昇順
  170.           cmp   al,'a'
  171.           jb    @i0004
  172.             mov     word ptr [si+2],NORMAL
  173.             sub     al,'a'-'A'
  174. ;       @else                       ; 降順
  175.           jmp short @i0005
  176. @i0004:
  177.             mov     word ptr [si+2],REVERSE
  178. ;       @ifend
  179. @i0005:
  180. ;       @cbegin
  181. ;       @case (al,=,'D'),S          ; 最終更新日付
  182.           cmp   al,'D'
  183.           jne   @c0005
  184.             mov     ax,offset _text:cmpdate
  185. ;       @case (al,=,'E'),S          ; 拡張子 3バイト
  186.           jmp short @c0004
  187. @c0005:
  188.           cmp   al,'E'
  189.           jne   @c0006
  190.             mov     ax,offset _text:cmpextn
  191. ;       @case (al,=,'F'),S          ; フルネーム 11バイト
  192.           jmp short @c0004
  193. @c0006:
  194.           cmp   al,'F'
  195.           jne   @c0007
  196.             mov     ax,offset _text:cmpfull
  197. ;       @case (al,=,'N'),S          ; ファイル名 8バイト
  198.           jmp short @c0004
  199. @c0007:
  200.           cmp   al,'N'
  201.           jne   @c0008
  202.             mov     ax,offset _text:cmpname
  203. ;       @case (al,=,'S'),S          ; ファイルサイズ
  204.           jmp short @c0004
  205. @c0008:
  206.           cmp   al,'S'
  207.           jne   @c0009
  208.             mov     ax,offset _text:cmpsize
  209. ;       @case (al,=,'T'),S          ; 最終更新時刻
  210.           jmp short @c0004
  211. @c0009:
  212.           cmp   al,'T'
  213.           jne   @c0010
  214.             mov     ax,offset _text:cmptime
  215. ;       @other
  216.           jmp short @c0004
  217. @c0010:
  218.             jmp     usageout
  219. ;       @cend
  220. @c0004:
  221.         mov     [si],ax
  222.         lea     si,[si+4]
  223. ;   @doend
  224.       jmp   @d0002
  225. @d0003:
  226.     ret
  227. ;
  228. setsortfunc endp
  229. ;
  230. ;------------------------------------------------------------------------------
  231. ;
  232. ;   setsortobj
  233. ;       ソート対象選択オプション評価
  234. ;
  235. ;   TYPE    near call
  236. ;   IN  AL アーギュメント文字
  237. ;   OUT なし
  238. ;   保存レジスタ    AX以外
  239. ;
  240. ;------------------------------------------------------------------------------
  241. ;
  242. setsortobj  proc
  243. ;
  244.     inc     di
  245. ;   @do repeat
  246. @d0004:
  247.         mov     al,es:[di]
  248.         inc     di
  249. ;       @if (al,=,0)
  250.           or    al,al
  251.           jne   @i0006
  252. ;           @doexit
  253.               jmp   @d0005
  254. ;       @ifend
  255. @i0006:
  256. ;       @if (al,>=,'a'),S           ; 先頭に
  257.           cmp   al,'a'
  258.           jb    @i0007
  259.             mov     dirgather,HEAD
  260.             sub     al,'a'-'A'
  261. ;       @else                       ; 末尾に
  262.           jmp short @i0008
  263. @i0007:
  264.             mov     dirgather,TAIL
  265. ;       @ifend
  266. @i0008:
  267. ;       @cbegin
  268. ;       @case (al,=,'G'),S          ; ディレクトリの扱い
  269.           cmp   al,'G'
  270.           jne   @c0012
  271.             mov     sortfuncs,offset _text:cmpdirf
  272.             mov     ax,dirgather
  273.             mov     sortfuncs+2,ax
  274. ;       @case (al,=,'T'),S          ; 再帰呼び出し
  275.           jmp short @c0011
  276. @c0012:
  277.           cmp   al,'T'
  278.           jne   @c0013
  279.             mov     recursive,YES
  280. ;       @case (al,=,'N'),S          ; ソート無し
  281.           jmp short @c0011
  282. @c0013:
  283.           cmp   al,'N'
  284.           jne   @c0014
  285.             mov     sortexec,NO
  286. ;       @case (al,=,'F'),S          ; 掃き寄せ無し
  287.           jmp short @c0011
  288. @c0014:
  289.           cmp   al,'F'
  290.           jne   @c0015
  291.             mov     sweep,NO
  292. ;       @case (al,=,'A'),S          ; アーカイブ属性
  293.           jmp short @c0011
  294. @c0015:
  295.           cmp   al,'A'
  296.           jne   @c0016
  297.             xor     attribute,ARCHIVE
  298. ;       @case (al,=,'D'),S          ; ディレクトリ
  299.           jmp short @c0011
  300. @c0016:
  301.           cmp   al,'D'
  302.           jne   @c0017
  303.             xor     attribute,SUBDIR
  304. ;       @case (al,=,'V'),S          ; ボリュームラベル
  305.           jmp short @c0011
  306. @c0017:
  307.           cmp   al,'V'
  308.           jne   @c0018
  309.             xor     attribute,VOLUME
  310. ;       @case (al,=,'S'),S          ; システムファイル
  311.           jmp short @c0011
  312. @c0018:
  313.           cmp   al,'S'
  314.           jne   @c0019
  315.             xor     attribute,SYSTEM
  316. ;       @case (al,=,'H'),S          ; 隠しファイル
  317.           jmp short @c0011
  318. @c0019:
  319.           cmp   al,'H'
  320.           jne   @c0020
  321.             xor     attribute,HIDDEN
  322. ;       @case (al,=,'R'),S          ; 読み出しのみ可能
  323.           jmp short @c0011
  324. @c0020:
  325.           cmp   al,'R'
  326.           jne   @c0021
  327.             xor     attribute,RDONLY
  328. ;       @other
  329.           jmp short @c0011
  330. @c0021:
  331.             jmp     usageout
  332. ;       @cend
  333. @c0011:
  334. ;   @doend
  335.       jmp   @d0004
  336. @d0005:
  337.     ret
  338. ;
  339. setsortobj  endp
  340. ;
  341. ;------------------------------------------------------------------------------
  342. ;
  343. ;   cmpdummy
  344. ;       ダミー比較ルーチン 必ず = で終了
  345. ;
  346. ;   TYPE    near call
  347. ;   IN  なし
  348. ;   OUT AX=0 ZERO FLAG=1
  349. ;   保存レジスタ    AX以外
  350. ;
  351. ;------------------------------------------------------------------------------
  352. ;
  353. cmpdummy    proc
  354. ;
  355.     xor     ax,ax
  356.     ret
  357. ;
  358. cmpdummy    endp
  359. ;
  360. ;------------------------------------------------------------------------------
  361. ;
  362. ;   cmpdirf
  363. ;       ディレクトリ属性比較
  364. ;
  365. ;   TYPE    near call
  366. ;   IN      DS:0  エントリ1アドレス
  367. ;           DX:0  エントリ2アドレス
  368. ;   OUT     AX ディレクトリ:通常= -1  通常:ディレクトリ= 1  その他 0
  369. ;   保存レジスタ    AX以外
  370. ;
  371. ;------------------------------------------------------------------------------
  372. ;
  373. cmpdirf proc
  374. ;
  375.     mov     al,ds:[0bh]             ; 属性バイトの取り出し
  376.     push    es
  377.     mov     es,dx
  378.     mov     ah,es:[0bh]
  379.     pop     es
  380.     and     ax,01010h
  381.     cmp     al,ah
  382.     ja      dirfhead                ; Dir:File
  383.     jb      dirftail                ; File:Dir
  384.     xor     ax,ax                   ; 同じ属性
  385.     ret
  386. dirfhead:
  387.     mov     ax,-1
  388.     ret
  389. dirftail:
  390.     mov     ax,1
  391.     ret
  392. ;
  393. cmpdirf endp
  394. ;
  395. ;------------------------------------------------------------------------------
  396. ;
  397. ;   cmpfull
  398. ;       フルネーム比較
  399. ;
  400. ;   TYPE    near call
  401. ;   IN      DS:0  エントリ1アドレス
  402. ;           dx:0  エントリ2アドレス
  403. ;   OUT     AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  404. ;   保存レジスタ    bx,dx,bp,ds,es
  405. ;
  406. ;------------------------------------------------------------------------------
  407. ;
  408. cmpfull proc
  409. ;
  410.     mov     cx,11
  411.     xor     si,si
  412.     xor     di,di
  413.     call    strncmp
  414.     ret
  415. ;
  416. cmpfull endp
  417. ;
  418. ;------------------------------------------------------------------------------
  419. ;
  420. ;   cmpname
  421. ;       ファイル名比較
  422. ;
  423. ;   TYPE    near call
  424. ;   IN      DS:0  エントリ1アドレス
  425. ;           dx:0  エントリ2アドレス
  426. ;   OUT     AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  427. ;   保存レジスタ    bx,dx,bp,ds,es
  428. ;
  429. ;------------------------------------------------------------------------------
  430. ;
  431. cmpname proc
  432. ;
  433.     mov     cx,8
  434.     xor     si,si
  435.     xor     di,di
  436.     call    strncmp
  437.     ret
  438. ;
  439. cmpname endp
  440. ;
  441. ;------------------------------------------------------------------------------
  442. ;
  443. ;   cmpextn
  444. ;       拡張子比較
  445. ;
  446. ;   TYPE    near call
  447. ;   IN      DS:0  エントリ1アドレス
  448. ;           dx:0  エントリ2アドレス
  449. ;   OUT     AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  450. ;   保存レジスタ    bx,dx,bp,ds,es
  451. ;
  452. ;------------------------------------------------------------------------------
  453. ;
  454. cmpextn proc
  455. ;
  456.     mov     si,8                    ; 拡張子位置
  457.     mov     di,si
  458.     mov     cx,3
  459.     call    strncmp
  460.     ret
  461. ;
  462. cmpextn endp
  463. ;
  464. ;------------------------------------------------------------------------------
  465. ;
  466. ;   cmpsize
  467. ;       ファイルサイズ比較
  468. ;
  469. ;   TYPE    near call
  470. ;   IN  DS:0  エントリ1アドレス
  471. ;       DX:0  エントリ2アドレス
  472. ;   OUT AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  473. ;   保存レジスタ    bx,dx,si,di,bp,ds,es
  474. ;
  475. ;------------------------------------------------------------------------------
  476. ;
  477. cmpsize proc
  478. ;
  479.     push    es
  480.     mov     es,dx
  481.     mov     ax,es:[1ch]             ; エントリ2のファイルサイズ4バイト
  482.     mov     cx,es:[1eh]
  483.     pop     es
  484.     cmp     cx,ds:[1eh]             ; エントリ1と比較
  485.     ja      sizeabove
  486.     jb      sizebelow
  487.     cmp     ax,ds:[1ch]
  488.     ja      sizeabove
  489.     jb      sizebelow
  490.     xor     ax,ax
  491.     ret
  492. sizeabove:
  493.     mov     ax,-1
  494.     ret
  495. sizebelow:
  496.     mov     ax,1
  497.     ret
  498. ;
  499. cmpsize endp
  500. ;
  501. ;------------------------------------------------------------------------------
  502. ;
  503. ;   cmpdate
  504. ;       最終更新日付比較
  505. ;
  506. ;   TYPE    near call
  507. ;   IN  DS:0  エントリ1アドレス
  508. ;       DX:0  エントリ2アドレス
  509. ;   OUT AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  510. ;   保存レジスタ    bx,dx,si,di,bp,ds,es
  511. ;
  512. ;------------------------------------------------------------------------------
  513. ;
  514. cmpdate proc
  515. ;
  516.     mov     ax,ds:[18h]
  517.     push    es
  518.     mov     es,dx
  519.     cmp     ax,es:[18h]
  520.     pop     es
  521.     ja      dateabove
  522.     jb      datebelow
  523.     xor     ax,ax
  524.     ret
  525. dateabove:
  526.     mov     ax,1
  527.     ret
  528. datebelow:
  529.     mov     ax,-1
  530.     ret
  531. ;
  532. cmpdate endp
  533. ;
  534. ;------------------------------------------------------------------------------
  535. ;
  536. ;   cmptime
  537. ;       最終更新時刻比較
  538. ;
  539. ;   TYPE    near call
  540. ;   IN  DS:0  エントリ1アドレス
  541. ;       DX:0  エントリ2アドレス
  542. ;   OUT AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  543. ;   保存レジスタ    bx,dx,si,di,bp,ds,es
  544. ;
  545. ;------------------------------------------------------------------------------
  546. ;
  547. cmptime proc
  548. ;
  549.     mov     ax,ds:[16h]
  550.     push    es
  551.     mov     es,dx
  552.     cmp     ax,es:[16h]
  553.     pop     es
  554.     ja      timeabove
  555.     jb      timebelow
  556.     xor     ax,ax
  557.     ret
  558. timeabove:
  559.     mov     ax,1
  560.     ret
  561. timebelow:
  562.     mov     ax,-1
  563.     ret
  564. ;
  565. cmptime endp
  566. ;
  567. ;------------------------------------------------------------------------------
  568. ;
  569. ;   strncmp
  570. ;       文字列比較 漢字対応 漢字はANKより大きい
  571. ;
  572. ;   TYPE    near call
  573. ;   IN  CX 比較サイズ
  574. ;       DS:SI エントリ1アドレス
  575. ;       ES:DI エントリ2アドレス
  576. ;   OUT AX エントリ1<エントリ2= -1  エントリ1=エントリ2= 0  エントリ1>エントリ2= 1
  577. ;   保存レジスタ    bx,dx,si,di,bp,ds,es
  578. ;
  579. ;------------------------------------------------------------------------------
  580. ;
  581. strncmp proc    uses bx es
  582. ;
  583.     cld
  584.     mov     es,dx
  585. ;   @do until
  586. @d0006:
  587.         dec     cx
  588.         mov     ax,[si]             ; エントリ1 1文字取得
  589.         inc     si
  590.         call    chrtypes
  591. ;       @if (zf,off)
  592.           jz    @i0009
  593.             dec     cx
  594.             inc     si
  595. ;       @ifend
  596. @i0009:
  597. ;
  598.         mov     bx,ax
  599.         mov     ax,es:[di]          ; エントリ2 1文字取得
  600.         inc     di
  601.         call    chrtypes
  602. ;       @if (zf,off)
  603.           jz    @i0010
  604.             inc     di
  605. ;       @ifend
  606. @i0010:
  607.         cmp     bx,ax               ; 比較
  608.         ja      strabove
  609.         jb      strbelow
  610.         or      cx,cx
  611. ;   @doend (zf,on),or,(sf,on)
  612.       jz    @d0007
  613.       js    @d0007
  614.       jmp   @d0006
  615. @d0007:
  616. ;
  617.     xor     ax,ax
  618. streturn:
  619.     ret
  620. ;
  621. strabove:
  622.     mov     ax,1
  623.     jmp     streturn
  624. strbelow:
  625.     mov     ax,-1
  626.     jmp     streturn
  627. ;
  628. strncmp endp
  629. ;
  630. ;------------------------------------------------------------------------------
  631. ;
  632. ;   chrtypes
  633. ;       漢字判定
  634. ;
  635. ;   TYPE    near call
  636. ;   IN  AX 文字コード AL=第一バイト
  637. ;   OUT AX 判定後コード ANK:AH=0
  638. ;       ZERO FLAG AHのTEST結果
  639. ;   保存レジスタ    AX以外
  640. ;
  641. ;------------------------------------------------------------------------------
  642. ;
  643. chrtypes    proc
  644. ;
  645.     cmp     al,081h
  646.     jb      chrank
  647.     cmp     al,0a0h
  648.     jb      chrsjis
  649.     cmp     al,0e0h
  650.     jb      chrank
  651.     cmp     al,0fch
  652.     jbe     chrsjis
  653. chrank:
  654.     xor     ah,ah
  655.     ret
  656. chrsjis:
  657.     xchg    ah,al
  658.     test    ah,ah
  659.     ret
  660. ;
  661. chrtypes    endp
  662. ;
  663. ;------------------------------------------------------------------------------
  664. ;
  665. ;   dirlist
  666. ;       全てのディレクトリ名を検索して、そのパス名をバッファに格納する
  667. ;       ワイルドカード対応  FUNCTION    4EH,4FH
  668. ;
  669. ;   TYPE    near call
  670. ;   IN  検索情報構造体
  671. ;   OUT ディレクションフラグ アップ方向
  672. ;   保存レジスタ    bp,ds
  673. ;
  674. ;------------------------------------------------------------------------------
  675. ;
  676. dirlist    proc uses bx si
  677.         local copysiz,fnamsiz,saveds
  678. ;
  679.     mov     saveds,ds               ;DS セーブ
  680.     les     di,srchname             ;パス名の長さと、最終位置を獲得
  681.     mov     cx,0ffffh
  682.     cld
  683.     xor     al,al
  684.   repne scasb
  685.     not     cx
  686.     dec     cx
  687.     mov     fnamsiz,cx
  688.     mov     di,word ptr srchname
  689.     call    pathsep                 ; パス名中の最後の'\'位置を獲得
  690.     mov     copysiz,cx              ; バッファへの共通コピーサイズをセット
  691.     mov     di,word ptr srchname
  692.     mov     dx,es:[di]
  693. ;   @cbegin
  694. ;   @case (zf,on)                   ; セパレータなし
  695.       jnz   @c0023
  696. ;       @if (dx,=,'.'),or,(dx,=,'..')   ; カレント/親?
  697.           cmp   dx,'.'
  698.           je    @i0011
  699.           cmp   dx,'..'
  700.           jne   @i0012
  701. @i0011:
  702.             jmp parentdir
  703. ;       @ifend
  704. @i0012:
  705. ;   @case (fnamsiz,=,1),and,(dl,=,'\'),S ; ルート指定か?
  706.       jmp   @c0022
  707. @c0023:
  708.       cmp   fnamsiz,1
  709.       jne   @c0024
  710.       cmp   dl,'\'
  711.       jne   @c0024
  712.         mov     ah,19h              ; カレントドライブ取得
  713.         int     21h
  714.         add     al,'A'              ; ドライブ名作成
  715.         mov     ah,':'
  716.         jmp     rootpath
  717. ;   @case (cx,=,2),S                ; カレント/親 指定か?
  718.       jmp short @c0022
  719. @c0024:
  720.       cmp   cx,2
  721.       jne   @c0025
  722. ;       @if (dh,=,':')
  723.           cmp   dh,':'
  724.           jne   @i0013
  725. ;           @if (fnamsiz,=,2)
  726.               cmp   fnamsiz,2
  727.               jne   @i0014
  728.                 sub     namebuffsiz,4   ; ディレクトリ名バッファサイズチェック
  729. ;               @if (cf,on)
  730.                   jnc   @i0015
  731.                     add     namebuffsiz,4
  732.                     jmp     srchout
  733. ;               @ifend
  734. @i0015:
  735.                 cld
  736.                 les     di,namebuff
  737.                 mov     ax,dx           ; ドライブ名
  738.                 stosw
  739.                 mov     ax,'.'          ; カレントディレクトリ指定
  740.                 stosw
  741.                 mov     word ptr namebuff,di    ; 新オフセット設定
  742.                 jmp     srchout
  743. ;           @ifend
  744. @i0014:
  745. ;           @if (fnamsiz,<=,4)
  746.               cmp   fnamsiz,4
  747.               ja    @i0016
  748.                 mov ax,es:[di+2]
  749. ;               @if (ax,=,'.'),or,(ax,=,'..')
  750.                   cmp   ax,'.'
  751.                   je    @i0017
  752.                   cmp   ax,'..'
  753.                   jne   @i0018
  754. @i0017:
  755.                     jmp parentdir
  756. ;               @ifend
  757. @i0018:
  758. ;           @ifend
  759. @i0016:
  760. ;       @ifend
  761. @i0013:
  762. ;   @case (fnamsiz,=,3),and,(word ptr es:[di+1],=,'\:'),S ; ルート指定か?
  763.       jmp short @c0022
  764. @c0025:
  765.       cmp   fnamsiz,3
  766.       jne   @c0026
  767.       cmp   word ptr es:[di+1],'\:'
  768.       jne   @c0026
  769.         mov     ax,dx
  770. rootpath:
  771.         sub     namebuffsiz,3       ; バッファ残りサイズ確認
  772. ;       @if (cf,on)
  773.           jnc   @i0019
  774.             add     namebuffsiz,3
  775.             jmp     srchout
  776. ;       @ifend
  777. @i0019:
  778.         cld
  779.         les     di,namebuff         ; ドライブ名のみセット
  780.         stosw
  781.         xor     al,al
  782.         stosb
  783.         mov     word ptr namebuff,di
  784.         jmp     srchout
  785. ;   @cend
  786. @c0022:
  787. @c0026:
  788. ;
  789.     mov     ah,4eh                  ;最初のファイル名検索ファンクション
  790.     mov     cx,037h                 ;ボリュームラベル以外すべて
  791.     lds     dx,srchname
  792.     int     21h
  793. ;   @do while,(cf,off)
  794. @d0008:
  795.       jc    @d0009
  796.         mov     ds,saveds           ; DS 復元
  797.         les     di,dta
  798. ;       @if (byte ptr es:[di-9],on,10h) ;ディレクトリかどうかのチェック
  799.           test  byte ptr es:[di-9],10h
  800.           jz    @i0020
  801.             mov     dx,es:[di]      ; 再帰処理のさいに '.' '..' を外す
  802. ;           @if (subsearch,=,YES)
  803.               cmp   subsearch,YES
  804.               jne   @i0021
  805. ;               @if (dx,=,'.'),or,(dx,=,'..')
  806.                   cmp   dx,'.'
  807.                   je    @i0022
  808.                   cmp   dx,'..'
  809.                   jne   @i0023
  810. @i0022:
  811.                     jmp     skipperiod
  812. ;               @ifend
  813. @i0023:
  814. ;           @ifend
  815. @i0021:
  816.             mov     cx,13           ;DTA上のファイル名から、長さを獲得
  817.             xor     al,al
  818.             cld
  819.           repne scasb
  820.             sub     cx,13
  821.             neg     cx
  822.             mov     fnamsiz,cx      ;ファイル名長さをセーブ
  823.             add     cx,copysiz      ;残りバッファサイズのチェックと更新
  824.             sub     namebuffsiz,cx
  825. ;           @if (cf,on)
  826.               jnc   @i0024
  827.                 add     namebuffsiz,cx  ;不足
  828.                 jmp     short   srchout
  829. ;           @ifend
  830. @i0024:
  831.             les     di,namebuff     ;共通パス名のコピー
  832.             lds     si,srchname
  833.             mov     cx,copysiz
  834.           rep   movsb
  835.             mov     ds,saveds       ;ファイル名のコピー
  836.             lds     si,dta
  837.             mov     cx,fnamsiz
  838.             rep     movsb
  839.             mov     ds,saveds
  840.             mov     word ptr namebuff,di    ;新オフセットの設定
  841. ;       @ifend
  842. @i0020:
  843. skipperiod:
  844.         mov     ah,4fh              ;次のファイル名検索ファンクション
  845.         lds     dx,srchname
  846.         mov     cx,037h
  847.         int     21h                 ;見つかればパス名セーブ
  848. ;   @doend
  849.       jmp   @d0008
  850. @d0009:
  851.     mov ds,saveds
  852. srchout:
  853.     ret
  854. ;
  855. parentdir:
  856.     cld                             ; パス名長さを調べる
  857.     les     di,srchname
  858.     xor     ax,ax
  859.     mov     cx,-1
  860.   repne scasb
  861.     not     cx
  862.     sub     namebuffsiz,cx
  863. ;   @if (cf,on)
  864.       jnc   @i0025
  865.         add     namebuffsiz,cx      ;不足
  866.         jmp     short   srchout
  867. ;   @ifend
  868. @i0025:
  869.     les     di,namebuff             ;ファイル名のコピー
  870.     lds     si,srchname
  871.   rep movsb
  872.     mov     ds,saveds               ; DS 復元
  873.     mov     word ptr namebuff,di    ;新オフセットの設定
  874.     jmp     short   srchout
  875. ;
  876. dirlist    endp
  877. ;
  878. ;------------------------------------------------------------------------------
  879. ;
  880. ;   pathsep
  881. ;       パス名を調べて一番最後の':'か'\'までのバイト数を通知する
  882. ;
  883. ;   TYPE    near call
  884. ;   IN  CX      パス名長さ
  885. ;       ES:DI   パス名の先頭アドレス
  886. ;   OUT CX & ZERO FLAG 最後の':'or'\'までのバイト数 及び 0か?
  887. ;       DIR FLAG アップ方向
  888. ;   保存レジスタ    bx,si,bp,ds,es
  889. ;
  890. ;------------------------------------------------------------------------------
  891. ;
  892. pathsep     proc
  893. ;
  894. ;   @if (cx,/=,0)                   ; 0 でない時
  895.       or    cx,cx
  896.       je    @i0026
  897.         push    cx                  ; 長さをセーブ
  898.         xor     dx,dx               ; 位置を初期化
  899. ;       @do until
  900. @d0010:
  901.             mov     al,es:[di]      ; 文字獲得
  902.             inc     di
  903. ;           @cbegin
  904. ;           @case (al,=,':'),or,(al,=,'\'),S ; セパレータならば位置を記憶
  905.               cmp   al,':'
  906.               je    @c0028
  907.               cmp   al,'\'
  908.               jne   @c0029
  909. @c0028:
  910.                 mov     dx,cx
  911. ;           @case (al,<,81h),or,(al,>,0fch),S ; α/N なにもしない
  912.               jmp short @c0027
  913. @c0029:
  914.               cmp   al,81h
  915.               jb    @c0030
  916.               cmp   al,0fch
  917.               jbe   @c0031
  918. @c0030:
  919. ;           @case (al,>=,0a0h),and,(al,<=,0dfh),S ; カナ なにもしない
  920.               jmp short @c0027
  921. @c0031:
  922.               cmp   al,0a0h
  923.               jb    @c0032
  924.               cmp   al,0dfh
  925.               ja    @c0032
  926. ;           @other                  ; 漢字 第二バイト分を進める
  927.               jmp short @c0027
  928. @c0032:
  929.                 inc     di
  930.                 dec     cx          ; 残り0なら終了
  931.                 jz      analysend
  932. ;           @cend
  933. @c0027:
  934.             dec     cx              ; 残り0なら終了
  935. ;       @doend (zf,on)
  936.           jnz   @d0010
  937. analysend:
  938.         pop     cx                  ; パス名長を復元
  939. ;       @if (dx,/=,0),S             ; セパレータが有った時
  940.           or    dx,dx
  941.           je    @i0027
  942.             dec     dx              ; DX にはパス名最後からのオフセット
  943.             sub     cx,dx           ; 先頭からのオフセットに直す
  944. ;       @else
  945.           jmp short @i0028
  946. @i0027:
  947.             xor     cx,cx           ; セパレータが無い時は0
  948. ;       @ifend
  949. @i0028:
  950. ;   @ifend
  951. @i0026:
  952.     ret
  953. ;
  954. pathsep     endp
  955. ;
  956. ;------------------------------------------------------------------------------
  957. ;
  958. ;   dirfind
  959. ;       パス名をもとにディレクトリかを調べ、ディレクトリの開始クラスタ
  960. ;       と、存在するドライブ番号を通知する
  961. ;
  962. ;   TYPE    near call
  963. ;   IN  ES:DI パス名の先頭アドレス
  964. ;   OUT AX ディレクトリの開始クラスタ番号
  965. ;       DL ドライブ番号
  966. ;       CARRY FLAG ディレクトリ属性 0:DIR 1:OTHERまたはルートでファイル無し
  967. ;   保存レジスタ    bp,ds
  968. ;
  969. ;------------------------------------------------------------------------------
  970. ;
  971. dirfind     proc
  972. ;
  973.     call    strcopywild             ; 検索用パス名の作成
  974. ;
  975.     mov     ah,2fh                  ; DTA 取得
  976.     int     21h
  977. ;
  978.     mov     ah,4eh                  ; ファイル検索
  979.     mov     cx,3fh
  980.     int     21h
  981. ;   @if (cf,off)                    ; 見つかった
  982.       jc    @i0029
  983.         mov     ax,es:[bx+0fh]      ; ディレクトリの開始クラスタ取得
  984.         xor     dx,dx
  985.         mov     dl,es:[bx]          ; ディレクトリのドライブ番号取得
  986. ;   @ifend
  987. @i0029:
  988.     ret
  989. ;
  990. dirfind     endp
  991. ;
  992. ;------------------------------------------------------------------------------
  993. ;
  994. ;   strcopywild
  995. ;       指定されたパス名をPATHBUFFにコピーし、ワイルドカードを付加する
  996. ;
  997. ;   TYPE    near call
  998. ;   IN  ES:DI パス名の先頭アドレス
  999. ;   OUT PATHBUFF
  1000. ;       ES:DI PATHBUFFのアドレス
  1001. ;   保存レジスタ    bp,ds
  1002. ;
  1003. ;------------------------------------------------------------------------------
  1004. ;
  1005. strcopywild proc
  1006. ;
  1007.     cld                             ; パス名長さを調べる
  1008.     mov     cx,-1
  1009.     xor     ax,ax
  1010.     mov     si,di
  1011.   repne     scasb
  1012.     not     cx
  1013.     dec     cx
  1014.     mov     ax,ds                   ; パス名をPATHBUFFにコピー
  1015.     mov     dx,es
  1016.     mov     ds,dx
  1017.     mov     es,ax
  1018.     mov     di,offset pathbuff
  1019.     mov     dx,di
  1020.     rep     movsb
  1021.     mov     ds,ax                   ; ワイルドカード指定を付加
  1022.     mov     cx,5
  1023.     mov     si,offset wildcard
  1024.     rep     movsb
  1025. ;
  1026.     mov     di,offset pathbuff
  1027.     ret
  1028. ;
  1029. strcopywild endp
  1030. ;
  1031.     end
  1032.